/**
 * CS575 Software Design
 * Group 6
 * Group Members: Anthony Davidson, Kendra Scheesley, Lyndsey Whitman, Stephen Zakrewsky
 * Date: May 19, 2012
 * Main Author(s): Lyndsey Whitman
 * 
 * Modified: 6/1 Stephen Zakrewsky
 * Modified: 6/2 Kendra Scheesley
 */

package edu.drexel.cs575.a3;

import java.io.OutputStream;

public class Scale
{
	private WeighingMechanism	weighingMech;
	private ScaleOutput			outputComp;
	private PowerUnit			powerUnit;
	private Display				display;
	private Bill				bill;
	private Units				units;

	private double				tareValue;
	private double				currentWeight;							// In
																		// Newtons

	Scale()
	{
		this.units = Units.GRAMS;
		this.tareValue = 0.0;
		this.currentWeight = 0.0;
	}

	Scale(WeighingMechanism wm, ScaleOutput d, PowerUnit p, Units u)
	{
		this.weighingMech = wm;
		this.outputComp = d;
		this.powerUnit = p;
		this.units = u;
		this.tareValue = 0.0;
		this.currentWeight = 0.0;
	}

	public void tare()
	{
		if (this.currentWeight > 0.0)
		{
			this.tareValue = -this.currentWeight;
		} else
		{
			this.tareValue = 0.0;
		}
	}

	public void addItem(WeighableItem item)
	{
		this.calculateWeight(item.getMass());

		// offset the display weight by the tare value
		double displayWeight = this.currentWeight + this.tareValue;

		// convert the weight to the current units
		displayWeight = UnitConverter.getInstanceForUnit(units).convertWeight(displayWeight);

		int numItems = item.getNumberOfItems();

		String displayName = numItems + " " + item.getName();

		if (numItems > 1)
		{
			displayName += "s";
		}

		this.displayItem(displayName, item.calculatePricePerMassUnit(), displayWeight);
	}

	public void removeItem(WeighableItem item)
	{
		this.currentWeight = 0.0;
	}

	public void powerOn(boolean on)
	{
		powerUnit.setPowerOn(on);
	}

	public void setUnits(Units units)
	{
		this.units = units;
	}

	public void setPowerUnit(PowerUnit powerUnit)
	{
		this.powerUnit = powerUnit;
	}
	
	public void setDisplay(Display display)
	{
		this.display = display;
	}
	
	public void setBill(Bill bill)
	{
		this.bill = bill;
	}

	public void setOutput(ScaleOutput output)
	{
		this.outputComp = output;
	}

	public void setWeighingMechanism(WeighingMechanism weighingMech)
	{
		this.weighingMech = weighingMech;
	}

	private void calculateWeight(double mass)
	{
		double massInKiloGrams = mass / 1000.0;

		this.currentWeight = this.weighingMech.addItem(massInKiloGrams);
	}

	private void displayItem(String name, double price, double weight)
	{
		this.outputComp.displayItem(name, price, weight, units.toString());
	}
	
	public void setBillOutputStream(OutputStream out)
	{
		this.bill.setOutputStream(out);
	}
	
	public Display getDisplay()
	{
		return this.display;
	}
	
	public Bill getBill()
	{
		return this.bill;
	}
}
